#ifndef __LSW_H__
#define __LSW_H__

#define SMI_PHY_DEVADDR(port) (0x0 + (port))
#define SMI_PORT_DEVADDR(port) (0x10 + (port))
#define SMI_GLOBAL1_DEVADDR 0x1B
#define SMI_GLOBAL2_DEVADDR 0x1C

#define SMI_PORT_ID_REG 0x3
#define SMI_PHY_CMD_REG 0x18
#define SMI_PHY_DATA_REG 0x19

#define SMI_SPEC_CR_REG 0x10

#define SMI_BUSY 0x1
#define SMI_IDLE 0x0
#define SMI_CLAUSE_22 0x1
#define SMI_CLAUSE_45 0X0
#define SMI_READ 0x2
#define SMI_WRITE 0x1

#define LSW_CDEV_NAME "lsw"
#define LSW_IOC_MAGIC 'L'
#define LSW_IO_READ _IOR(LSW_IOC_MAGIC, 50, unsigned int)
#define LSW_IO_WRITE _IOW(LSW_IOC_MAGIC, 51, unsigned int)

#define LSW_PORT_0 0
#define LSW_PORT_1 1
#define LSW_PORT_2 2
#define LSW_PORT_3 3
#define LSW_PORT_4 4
#define LSW_PORT_5 5
#define LSW_PORT_6 6

#define STATIC

typedef union {
    struct {
        unsigned int regaddr : 5; /* [4:0]: smi register addr bits */
        unsigned int devaddr : 5; /* [9:5]: smi device addr bits */
        unsigned int smiop : 2;   /* [11:10]: SMI Opcode */
        unsigned int smimode : 1; /* [12]: SMI Mode bit, Clause 45 or 22 */
        unsigned int resv : 2;    /* [14:13]: reserved */
        unsigned int smibusy : 1; /* [15]: SMI unit busy */
    } bits;
    unsigned short value;
} smi_cmd_reg;

struct lsw_dev {
    struct mii_bus *bus;
    struct class *lsw_cdev_cls;
    struct cdev lsw_cdev;
    dev_t devno;
};

struct lsw_arg {
    u16 devaddr;
    u16 regaddr;
    u16 value_in;
    u16 value_out;
};

#endif
